package br.ufal.ic.ml;

import java.util.ArrayList;
import java.util.List;


public class RunnerAwayEnvironment extends Environment {

	private int height;
	private int width;
	private List<Sensation> sensationList;
	boolean[][] tabuleiro;
	
	public void init(int size) {
		height = size;
		width = size;
		sensationList = new ArrayList<Sensation>();
		tabuleiro = new boolean[size][size];
		
		for(int i = 0; i < size; ++i) {
			for(int j = 0; j < size; ++j) {
				tabuleiro[i][j] = true;
			}
		}
		
	}
	
	@Override
	public List<Sensation> start_trial() {
		Sensation2D s0 = new Sensation2D(50, 50);
		Sensation2D s1 = new Sensation2D(0, 0);
		Sensation2D s2 = new Sensation2D(0, 99);
		Sensation2D s3 = new Sensation2D(99, 0);
		Sensation2D s4 = new Sensation2D(99, 99);
		
		tabuleiro[50][50] = false;
		tabuleiro[0][0] = false;
		tabuleiro[0][99] = false;
		tabuleiro[99][0] = false;
		tabuleiro[99][99] = false;
		
		sensationList.add(s0);
		sensationList.add(s1);
		sensationList.add(s2);
		sensationList.add(s3);
		sensationList.add(s4);
		
		return sensationList;
	}
	
	/**
	 * 
	 * @param action Ação a ser tomada
	 * @return Reward
	 */
	public double step(Action action, int id) {
		int acao = ((RunnerAwayAction)action).getValue();
		Sensation2D currentSensation = (Sensation2D) sensationList.get(id);
		/*
		 * Se der problema no indice do array tabuleiro, dividir a expressão em 2 ifs aninhados xD
		 */
		switch(acao) {
		case 0:
			if(!(currentSensation.getX() - 1 < 0) && 
					tabuleiro[currentSensation.getX() - 1][currentSensation.getY()]) {
				tabuleiro[currentSensation.getX()][currentSensation.getY()] = true;
				tabuleiro[currentSensation.getX() - 1][currentSensation.getY()] = false;
				currentSensation.setX(currentSensation.getX() - 1); 
			}			
			break;
		case 1:
			if(!(currentSensation.getX() + 1 > 99) && 
					tabuleiro[currentSensation.getX() + 1][currentSensation.getY()]) {
				tabuleiro[currentSensation.getX()][currentSensation.getY()] = true;
				tabuleiro[currentSensation.getX() + 1][currentSensation.getY()] = false;
				currentSensation.setX(currentSensation.getX() + 1); 
			}			
			break;
		case 2:
			if(!(currentSensation.getY() - 1 < 0) && 
					tabuleiro[currentSensation.getX()][currentSensation.getY() - 1]) {
				tabuleiro[currentSensation.getX()][currentSensation.getY()] = true;
				tabuleiro[currentSensation.getX()][currentSensation.getY() - 1] = false;
				currentSensation.setY(currentSensation.getY() - 1); 
			}
			break;
		case 3:
			if(!(currentSensation.getY() + 1 > 99) && 
					tabuleiro[currentSensation.getX()][currentSensation.getY() + 1]) {
				tabuleiro[currentSensation.getX()][currentSensation.getY()] = true;
				tabuleiro[currentSensation.getX()][currentSensation.getY() + 1] = false;
				currentSensation.setY(currentSensation.getY() + 1); 
			}
			break;
		}
		return (id == 0) ? isTheEnd() : 0;
	}

	private double isTheEnd() {
		Sensation2D endSensation = (Sensation2D) sensationList.get(0);
		boolean[] canGo = new boolean[4];
		
		if(!(endSensation.getX() - 1 < 0) && 
				!tabuleiro[endSensation.getX() - 1][endSensation.getY()]) {
			canGo[0] = false;
		}
		if((endSensation.getX() + 1 > 99) && 
				!tabuleiro[endSensation.getX() + 1][endSensation.getY()]) {
			canGo[1] = false;
		}
		if((endSensation.getY() - 1 < 0) && 
		!tabuleiro[endSensation.getX()][endSensation.getY() - 1]) {
			canGo[2] = false;
		}
		if((endSensation.getY() + 1 > 99) && 
				!tabuleiro[endSensation.getX()][endSensation.getY() + 1]) {
			canGo[3] = false;
		}
		if(canGo[0] || canGo[1] || canGo[2] || canGo[3]) {
			return 0;
		}
		else {
			return -100;
		}
	}

	@Override
	public void init(int argc, char[] argv) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void step(Action action, Sensation nextSensation, double reward) {
		// TODO Auto-generated method stub
		
	}
	
}